#include <FL/Fl.H>
#include <FL/Fl_Box.H>
#include <FL/Fl_Double_Window.H>
#include <FL/Fl_JPEG_Image.H>
#include <FL/Fl_Shared_Image.H>
#include <FL/fl_draw.H>

#include "tcp_client.h"
#include <chrono>
#include <iostream>
#include <mutex>
#include <thread>
#include <algorithm>

using namespace std;
using Ohscrcpy::TcpClient;

namespace {
Fl_JPEG_Image *currentImage;
Fl_JPEG_Image *imageFromServer;
mutex imageMutex;

Fl_Double_Window *window;
Fl_Box *imageBox;

bool needRedrawImage;

int frameCnt;
long fpsStartTime;

int windowHeight;
int windowWidth;
}

long getCurrentTimeMs() {
    return chrono::time_point_cast<chrono::milliseconds>(chrono::system_clock::now()).time_since_epoch().count();
}

void requestImage() {
    TcpClient tcpClient;
    if (!tcpClient.Init()) {
        cout << "init failed" << endl;
        exit(1);
    }

    if (!tcpClient.Connect("127.0.0.1", 8000)) {
        cout << "connect failed" << endl;
        exit(1);
    }

    while (true) {
        if (needRedrawImage) {
            continue;
        }

        imageMutex.lock();

        if (imageFromServer != nullptr) {
            imageMutex.unlock();
            continue;
        }

        int size = 0;
        if (tcpClient.Recv(reinterpret_cast<char *>(&size), 4) != 4 || size <= 0) {
            cout << "recv size error, size=" << size << endl;
            // todo 处理有点问题，获取不到应该等待？
            exit(1);
        }

        char *data = new char[size];
        int recvSize = tcpClient.Recv(data, size);
        if (recvSize != size) {
            cout << "recv data error, size=" << size << ", recvSize=" << recvSize << endl;
            exit(1);
        }

        imageFromServer = new Fl_JPEG_Image(nullptr, (unsigned char *)data);
        needRedrawImage = true;

        imageMutex.unlock();
    }
}

int main() {
    fl_register_images();

    thread request(requestImage);
    request.detach();

    // 获取第一张图片，确定横竖屏状态
    while (true) {
        imageMutex.lock();

        if (imageFromServer == nullptr) {
            imageMutex.unlock();
            continue;
        }
        currentImage = imageFromServer;
        imageFromServer = nullptr;
        needRedrawImage = false;

        imageMutex.unlock();
        break;
    }

    cout << "window: h=" << Fl::h() << ", w=" << Fl::w() << endl;
    cout << "image: h=" << currentImage->h() << ", w=" << currentImage->w() << endl;

    if (currentImage->w() < currentImage->h()) {
        // 宽度小于高度，视为竖屏状态，窗口高度取显示器短边的0.85倍，宽度按图片比例计算
        windowHeight = min(Fl::h(), Fl::w()) * 0.85;
        windowWidth = windowHeight * currentImage->w() / 1.0 / currentImage->h();
    } else {
        // 横屏状态，窗口宽度取显示器短边的0.85倍，高度按图片比例计算
        windowWidth = min(Fl::h(), Fl::w()) * 0.85;
        windowHeight = windowWidth * currentImage->h() / 1.0 / currentImage->w();
    }

    window = new Fl_Double_Window(windowWidth, windowHeight, "OHSC");
    imageBox = new Fl_Box(0, 0, windowWidth, windowHeight);
    imageBox->image(currentImage);
    currentImage->scale(windowWidth, windowHeight);
    window->end();
    window->show();

    frameCnt = 1;
    fpsStartTime = getCurrentTimeMs();

    Fl::add_idle([](void *) {
        long nowTime = getCurrentTimeMs();
        long duration = nowTime - fpsStartTime;
        // 帧率信息更新间隔为1s
        if (duration >= 1000) {
            window->label(("OhScrCpy  " + to_string((int)(frameCnt * 1000.0 / duration)) + "fps").data());
            frameCnt = 0;
            fpsStartTime = nowTime;
        }

        if (!needRedrawImage) {
            return;
        }

        imageMutex.lock();

        if (imageFromServer == nullptr) {
            imageMutex.unlock();
            return;
        }

        imageBox->image(imageFromServer);
        delete currentImage;
        currentImage = imageFromServer;
        imageFromServer = nullptr;
        needRedrawImage = false;

        imageMutex.unlock();

        currentImage->scale(windowWidth, windowHeight);
        imageBox->redraw();
        frameCnt++;
    });

    return Fl::run();
}